package com.shinbada.core.persistence;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.shinbada.common.Common;
import com.shinbada.common.tree.TreeLevelUtil;
import com.shinbada.common.utils.IdGen;
import com.shinbada.config.swagger.IgnoreSwaggerParameter;
import com.shinbada.core.persistence.genrule.DefalutGenRuleEnumSingleton;
import com.shinbada.core.persistence.genrule.IdGenRule;
import com.shinbada.excel.annotation.ExcelField;
import com.shinbada.modules.sys.entity.Office;
import com.shinbada.modules.sys.entity.User;
import com.shinbada.modules.sys.utils.UserUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;

import java.util.Date;

/**
 * 数据Entity类
 *
 * @author initcap
 * @version 2017-05-16
 */
@Data
@Slf4j
public abstract class DataEntity<T> extends BaseEntity<T> {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("主键生成规则")
    @IgnoreSwaggerParameter
    @JsonIgnore
    protected transient IdGenRule idGenRule;
    @ApiModelProperty("备注")
    @ExcelField(value = "备注信息")
    @Length(min = 0, max = 255)
    protected String remarks;
    @ApiModelProperty("扩展参数")
    protected Variables variables;
    @ApiModelProperty("公司主键")
    protected String companyId;
    @ApiModelProperty("域路径")
    @IgnoreSwaggerParameter
    protected String domainPath;
    @IgnoreSwaggerParameter
    protected User createBy;
    @IgnoreSwaggerParameter
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    protected Date createDate;
    @IgnoreSwaggerParameter
    protected User updateBy;
    @IgnoreSwaggerParameter
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    protected Date updateDate;
    /**
     * 删除标记（0：正常；1：删除；2：审核）
     */
    @IgnoreSwaggerParameter
    @Length(min = 1, max = 1)
    protected String delFlag;

    public DataEntity() {
        super();
        this.delFlag = DEL_FLAG_NORMAL;
    }

    public DataEntity(String id) {
        super(id);
    }

    /**
     * 这里主要处理以下几种场景，不足的请补充
     * 1. 超级管理，指定companyId添加数据
     * 2. 超级管理，不指定companyId，添加时获取超级管理员的companyId
     * 3. 没登录用户，并且没有设置companyId，给默认的机构
     * 4. 没登录用户，设置companyId,采用设置的companyId
     * 5. 系统用户，执行系统任务，指定companyId
     *
     * @return 机构标识
     */
    public String getCompanyId() {
        User user = UserUtils.getUser();
        if (user.getCompany() != null) {
            // 超级管理员是有可能进行指定companyId的
            boolean supper = user.isAdmin() && StringUtils.isBlank(this.companyId);
            // 普通用户没有权利指定companyId
            boolean simple = !user.isAdmin();
            if (supper || simple) {
                this.companyId = user.getCompany().getId();
            }
        }
        return companyId;
    }

    /**
     * 插入之前执行方法，需要手动调用
     */
    @Override
    public void preInsert() {
        if (!this.isNewRecord) {
            if (IDTYPE_UUID.equals(this.getIdType())) {
                setId(IdGen.uuid());
            } else if (IDTYPE_AUTO.equals(this.getIdType())) {
                //使用自增长不需要设置主键
                setId(null);
            } else if (IDTYPE_SNOW.equals(this.getIdType())) {
                setId(IdGen.snowflake());
            } else if (IDTYPE_MANUAL.equals(this.getIdType())) {
                // 用户手动传主键，不用处理
            } else if (IDTYPE_RULE.equals(this.getIdType())) {
                if (getIdGenRule() == null) {
                    setId(DefalutGenRuleEnumSingleton.INSTANCE.genCode());
                } else {
                    setId(getIdGenRule().genCode());
                }
            }

        }
        User user = UserUtils.getUser();
        if (StringUtils.isNotBlank(user.getId())) {
            this.updateBy = user;
            this.createBy = user;
            log.info("【添加数据】preInsert: 公司主体为  : {}", getCompanyId());
        }
        // 设置域，默认的就是当前用户的主管理域
        if (StringUtils.isBlank(this.domainPath)) {
            Office office = user.getOffice();
            if (office == null) {
                if (user.isAdmin()) {
                    this.domainPath = Common.SYSTEM_DOMAIN_PATH;
                } else if (user.getCompany() != null) {
                    this.domainPath = user.getCompany().getParentIds();
                } else {
                    this.domainPath = TreeLevelUtil.ROOT.concat(TreeLevelUtil.SEPARATOR).concat(companyId == null ? "" : companyId);
                }
            } else {
                this.domainPath = office.getParentIds();
            }
        }
        this.updateDate = new Date();
        this.createDate = this.updateDate;
    }

    /**
     * 更新之前执行方法，需要手动调用
     */
    @Override
    public void preUpdate() {
        User user = UserUtils.getUser();
        if (StringUtils.isNotBlank(user.getId())) {
            this.updateBy = user;
        }
        this.updateDate = new Date();
    }

}
